/**
 * 48. 旋转图像
 */
public class Solution_48 {
    /**
     * 方法二：用翻转代替旋转
     * <p>
     * 顺时针旋转 90 度，相当于对矩阵先进行上下翻转，再进行主对角线翻转
     * <p>
     * 时间复杂度：O(N^2)
     * 空间复杂度：O(1)
     */
    public void rotate(int[][] matrix) {
        int n = matrix.length;
        // 上下翻转
        for (int i = 0; i < n / 2; i++) {
            for (int j = 0; j < n; j++) {
                int temp = matrix[i][j];
                matrix[i][j] = matrix[n - 1 - i][j];
                matrix[n - 1 - i][j] = temp;
            }
        }
        // 主对角线翻转
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < i; j++) {
                int temp = matrix[i][j];
                matrix[i][j] = matrix[j][i];
                matrix[j][i] = temp;
            }
        }
    }

    /**
     * 方法一：使用辅助数组
     * <p>
     * 顺时针旋转 90 度后，原来的第一行变成了最后一列，第二行变成了倒数第二列，依此类推
     * <p>
     * 时间复杂度：O(N^2)
     * 空间复杂度：O(N^2)
     */
    public void rotate1(int[][] matrix) {
        int n = matrix.length;
        int[][] temp = new int[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                temp[j][n - 1 - i] = matrix[i][j];
            }
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                matrix[i][j] = temp[i][j];
            }
        }
    }

    public static void main(String[] args) {
        Solution_48 solution = new Solution_48();
        int[][] matrix = { 
            { 5, 1, 9, 11 }, 
            { 2, 4, 8, 10 }, 
            { 13, 3, 6, 7 }, 
            { 15, 14, 12, 16 } 
        };
        solution.rotate(matrix);
        int n = matrix.length;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                System.out.print(matrix[i][j] + "\t");
            }
            System.out.println();
        }
    }
}
